Skip to content

Add Build Flow view for better visualization of Upstream and Downstream Builds - #1312

Open
adityajalkhare wants to merge 13 commits into
jenkinsci:mainfrom
adityajalkhare:feature/issue-1310-e2e-build-flow
Open

Add Build Flow view for better visualization of Upstream and Downstream Builds#1312
adityajalkhare wants to merge 13 commits into
jenkinsci:mainfrom
adityajalkhare:feature/issue-1310-e2e-build-flow

Conversation

@adityajalkhare

@adityajalkhare adityajalkhare commented May 26, 2026

Copy link
Copy Markdown
Contributor

Closes #1310

Summary

Adds a Build Flow view that renders upstream and downstream build-trigger relationships as an interactive, zoomable directed graph. Uses the shared Jenkins Design Library status icons, Tippy.js dropdowns, and react-zoom-pan-pinch for pan/zoom.

Screenshots/Demo

Over-Complicated Job

Screenshot

image

Live Video

Build.Flow.Demo.-.Pipeline.Graph.Plugin.mov

Focused View of a Job

Focused.View.of.a.Job.-.Build.Flow.mov

Simple Job

Build Flow Tab

bbuild-flow-tab

Overview Tab

overview-tab

Job Page

job-page

Features

  • Directed graph (DAG) layout with bezier-curve edges
  • Zoom, pan, fit-to-view
  • Toggle upstream/downstream builds independently
  • Switch between LTR and TTB layout directions
  • Flatten to grid mode for large pipelines
  • Focus-path highlighting on hover
  • Staggered entrance animations for nodes and edges
  • Display toggles: duration, build number, full names, description
  • Up to 6 recent result dots per node (clickable)
  • Auto-refresh (5s) while any build is in-progress
  • Safety caps: 200 nodes, 50 depth
  • Full i18n support
  • Accessibility: aria labels, reduced-motion, high-contrast, forced-colors

Where it appears

Context View
Build overview tab Embedded card (350px height)
Build sidebar Full-page dedicated view
Job sidebar Latest build's flow

Detection method

Trigger-based only. Uses Cause.UpstreamCause and DownstreamBuildAction. Does not scan artifacts or copyArtifacts relationships.

Implementation

Layer Files Role
Frontend BuildFlow.tsx, BuildFlowLayout.ts, BuildFlowUtils.ts, BuildFlow.scss React component, DAG layout algorithm, utilities, styling
Model BuildFlowModel.ts, BuildFlowNode.java, BuildFlowEdge.java Shared types for the graph response
Backend BuildFlowGraph.java, BuildFlowResponse.java Traverses build chain, computes DAG, serializes JSON
Actions BuildFlowAction.java, BuildFlowJobAction.java + factories Sidebar links, API endpoint at buildFlow/graph
Views 6 Jelly files Renders in new + legacy Jenkins UI modes

Testing

  • Frontend: 214 tests across 27 files (vitest) - layout, utilities, SCSS tokens, focus-path, status mapping
  • Backend: 7 integration tests (@WithJenkins) - graph traversal, edge cases, parallel/nested stages
  • Manual: Verified with mvn hpi:run on sequential, parallel, nested-stage, and multi-branch pipelines

@adityajalkhare
adityajalkhare marked this pull request as ready for review May 26, 2026 12:45
@adityajalkhare
adityajalkhare requested a review from a team as a code owner May 26, 2026 12:45
@KalleOlaviNiemitalo

Copy link
Copy Markdown

Does this detect upstream/downstream relationships solely from how builds are triggered, or does this also detect if a downstream build is triggered by something unrelated (e.g. cron) and then uses the copyArtifacts step to copy artifacts from an upstream build?

I'm asking because we can get hundreds of downstream builds in the copyArtifacts case and I'm concerned that looking up all of those could be excessively slow.

@adityajalkhare

Copy link
Copy Markdown
Contributor Author

@KalleOlaviNiemitalo

Thanks for calling this out. I checked the implementation to make sure before replying.

This feature is trigger-based only, not artifact-based.

  • Upstream detection uses CauseAction / Cause.UpstreamCause in getUpstreamBuild(...).
  • Downstream detection uses DownstreamBuildAction in getDownstreamBuilds(...).
  • Queued downstream items are also linked only through Cause.UpstreamCause.
  • There is no copyArtifacts-specific detection logic in this feature.

So if a build starts independently, for example from cron, and then uses copyArtifacts from some other build, this implementation would not treat that build as downstream.

So the graph is following explicit build-trigger relationships, not artifact-consumption relationships.

On the performance concern, this code is not scanning all builds looking for artifact usage. It reads trigger metadata from the current build chain, and it also has hard safety caps:

  • MAX_NODES = 200
  • MAX_DEPTH = 50

So the case of getting hundreds of downstream builds purely because of copyArtifacts should not apply here.

That said, I do not have an exact or near-replica of your pipeline setup locally, so if you have a representative case handy, please feel free to test it. If it behaves differently in practice, I can follow up and revert or adjust the implementation as needed.

- Extract all inline SVGs into BuildFlowIcons.tsx with a reusable
  ToggleButton component
- Deduplicate element-ID lookup via shared getRootElement() export
- Unify statusColor/resultDotColor into a single STATUS_COLORS map
- Extract shared SCSS into _card-heading.scss and _card-controls.scss
  mixins, replacing verbatim copies in BuildFlow.scss, stages.scss,
  and pipeline-graph-view/app.scss
- Add status-stripe mixin and $icon-inline-offset variable to reduce
  repeated SCSS patterns
- Visual polish: status-colored left border with tinted background,
  node entry animation, edge fade-in, focus-visible ring, shared
  StatusIcon integration
- Add BuildFlowScss.spec.ts and FocusPath.spec.ts
@adityajalkhare
adityajalkhare marked this pull request as ready for review May 28, 2026 16:38
@novinxy

novinxy commented May 29, 2026

Copy link
Copy Markdown

Looks awesome! 😍
Does it work when upstream triggers downstream with build step ?

@timja

timja commented May 29, 2026

Copy link
Copy Markdown
Member

I used this to re-create your screenshot:

image
import com.cloudbees.hudson.plugins.folder.Folder
import org.jenkinsci.plugins.workflow.job.WorkflowJob
import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition
import jenkins.model.Jenkins

// ---------------------------------------------------------------------------
// Recreates the upstream/downstream "Build Flow" pipeline jobs under issues/1310.
//
// Wiring (upstream -> downstream). Where a job has several upstreams it gets
// triggered once per upstream, which is why e2e-tests and deploy-staging show
// up as multiple runs in the Build Flow view.
// ---------------------------------------------------------------------------

def downstream = [
    'root'              : ['frontend-build', 'backend-build', 'mobile-build'],
    'frontend-build'    : ['frontend-unit-test', 'frontend-lint'],
    'backend-build'     : ['backend-unit-test', 'backend-lint', 'backend-security'],
    'mobile-build'      : ['mobile-unit-test'],
    'frontend-unit-test': ['e2e-tests'],
    'frontend-lint'     : ['e2e-tests'],
    'backend-unit-test' : ['integration-tests'],
    'backend-lint'      : ['integration-tests'],
    'backend-security'  : ['integration-tests'],
    'mobile-unit-test'  : ['mobile-e2e'],
    'e2e-tests'         : ['deploy-staging'],
    'integration-tests' : ['deploy-staging'],
    'mobile-e2e'        : [],
    'deploy-staging'    : [],
]

def jenkins = Jenkins.get()
def rng = new Random()

// --- ensure folder path issues/1310 ---------------------------------------
def getOrCreateFolder = { ItemGroup parent, String name ->
    def existing = parent.getItem(name)
    if (existing instanceof Folder) {
        return existing
    }
    if (existing != null) {
        existing.delete() // wrong type, replace it
    }
    parent.createProject(Folder, name)
}

def issues = getOrCreateFolder(jenkins, 'issues')
def folder = getOrCreateFolder(issues, '1310')

// --- build the pipeline script for a job -----------------------------------
def scriptFor = { String name, List<String> kids ->
    def secs = 2 + rng.nextInt(7) // 2..8s so the tree completes quickly
    def sb = new StringBuilder()
    sb << "pipeline {\n"
    sb << "  agent any\n"
    sb << "  stages {\n"
    sb << "    stage('${name}') {\n"
    sb << "      steps {\n"
    sb << "        echo 'Running ${name}'\n"
    sb << "        sleep time: ${secs}, unit: 'SECONDS'\n"
    sb << "      }\n"
    sb << "    }\n"
    if (kids) {
        sb << "    stage('trigger downstream') {\n"
        sb << "      steps {\n"
        kids.each { kid ->
            // relative name resolves within the same folder
            sb << "        build job: '${kid}', wait: false, propagate: false\n"
        }
        sb << "      }\n"
        sb << "    }\n"
    }
    sb << "  }\n"
    sb << "}\n"
    sb.toString()
}

// --- create / update each job ---------------------------------------------
downstream.each { name, kids ->
    def job = folder.getItem(name)
    if (!(job instanceof WorkflowJob)) {
        if (job != null) {
            job.delete()
        }
        job = folder.createProject(WorkflowJob, name)
    }
    job.definition = new CpsFlowDefinition(scriptFor(name, kids), true)
    job.save()
    println "Configured ${job.fullName}"
}

println "\nDone. Created/updated ${downstream.size()} jobs under ${folder.fullName}."
println "Trigger the flow with:  Jenkins.get().getItemByFullName('issues/1310/root').scheduleBuild2(0)"

// Uncomment to kick off the whole tree immediately:
// folder.getItem('root').scheduleBuild2(0)

Comment thread src/main/frontend/build-flow-view/build-flow/main/BuildFlow.scss Outdated
@adityajalkhare

Copy link
Copy Markdown
Contributor Author

@novinxy - yes. I used that only.
image

@timja

timja commented May 29, 2026

Copy link
Copy Markdown
Member

I haven’t looked in detail yet and will need more time and ideally feedback from others
Some initial thoughts:

  • the pipeline you are actively viewing (how it adds dashed lines) feels a bit strange to me. It took me a bit to work out why it was dashed I think this could be communicated differently.
  • I’m not sure on the second widget for it on the build and job pages. Maybe there should be a button for swapping between the two widgets? I get it makes it more discoverable but we don’t want lots of widgets piled on that page as it will get full quickly

@adityajalkhare

Copy link
Copy Markdown
Contributor Author

@timja

the pipeline you are actively viewing (how it adds dashed lines) feels a bit strange to me. It took me a bit to work out why it was dashed I think this could be communicated differently.

Thanks, I did think about it but left it for community feedback because couldn't decide. The following is another design which Jenkins follows widely -

image

WDYT about this?

@timja

timja commented May 29, 2026

Copy link
Copy Markdown
Member

I'm not sure if the others need fading out but yes some sort of border to show 'active' or 'selected' would be better

@adityajalkhare

Copy link
Copy Markdown
Contributor Author

The fade out was not on select, it was on hover... I just took a screenshot at the wrong time :)

@novinxy

novinxy commented May 29, 2026

Copy link
Copy Markdown

For me fade out looks clear and makes it easy to see selected "flow"
But "active" border is also nice alternative :)

Those builds on each card are stages from the pipelines ?
Do they provide links to the stages ?
What happens if there are many stages like 100 in pipeline ?

Edit: Nvm, description answered that for me. Those are recent builds

@novinxy

novinxy commented May 29, 2026

Copy link
Copy Markdown

This flow shows pipeline relations, but is it easy to analyze individual flow of the builds?

I mean such situation:

  • we have 3 pipelines: A, B, C
  • A -> B -> C
  • they already have more than 5 runs
  • Scenario A: Pipeline A fails without triggering B. Last Build for A, B, C is "different build flow"
  • Scenario B: Pipeline A fails but triggered B, which triggered B, C. Last Build for A, B, C is "same build flow"
  • Is there option to differenciate scenario A and scenario B from those graphs ? Is it possible to track which build from pipeline A triggered which build from pipeline B?

If not then I think simple "active border" on each related run would be sufficient :)
So If I hover on one run, it will "active" and other cascade or runs will also active :)

@adityajalkhare

Copy link
Copy Markdown
Contributor Author

Just for clarification -

Selected/Active border on current job

image

Hover fade out (can still see the current job in the left side, but faded)

image

@novinxy

novinxy commented May 29, 2026

Copy link
Copy Markdown

Just for clarification -

Selected/Active border on current job

image ### Hover fade out (can still see the current job in the left side, but faded) image

Maybe hover effect should be disabled if it hides active pipeline ?

But with clicking on active card maybe we could enhance it better ? What if clicking could bring out pipeline flow? That could help in analyzing flow for complicated scenarios, e.g.
Click on one pipeline shows fades out all non-related pipelines, or changes border for all related ones
If we click on frontend-lint we make "green ones" more visible
image

what do you think about this idea ?
Sorry if I'm proposing something really difficult, I'm not frontend guy, so I don't know how difficult are such implementations 😅

@adityajalkhare

adityajalkhare commented May 29, 2026

Copy link
Copy Markdown
Contributor Author

Scenario A: Pipeline A fails without triggering B. Last Build for A, B, C is "different build flow"

The build flow does not load in this case for the latest build where A failed before triggering B.

Scenario B: Pipeline A fails but triggered B, which triggered B, C. Last Build for A, B, C is "same build flow"

If A fails after triggering B, which triggered C, and if wait: true was set, that means C was finished, then B, then some steps ran which failed, so the Build Flow would load.

_We can also test these scenarios for better understanding. _

Maybe hover effect should be disabled if it hides active pipeline ?

Hover is intended for a quick glance of the flow between job nodes (one parent and one child), while being anywhere in the graph, irrespective of the selected/active job.

But with clicking on active card maybe we could enhance it better ? What if clicking could bring out pipeline flow? That could help in analyzing flow for complicated scenarios, e.g.
Click on one pipeline shows fades out all non-related pipelines, or changes border for all related ones
If we click on frontend-lint we make "green ones" more visible

The though process, and what I have seen is - Bezier curves/Connector lines are the tracking mechanisms users use to track the flow.

I would prefer not fading the whole unrelated flow based on selected job, unless there is a strong reasoning since then the "here's the whole Build Flow" core idea and glancing through functionality would break.

When I think of it..... There is an hide/show upstream/downstream toggle, perhaps there can be another one, "View Active Job Flow/name something else" which can let us view what you suggested. @novinxy WDYT about this?

Sorry if I'm proposing something really difficult, I'm not frontend guy, so I don't know how difficult are such implementations 😅

I'm also just starting out, so no idea lol... ;)

@adityajalkhare

Copy link
Copy Markdown
Contributor Author

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new Build Flow view that visualizes upstream/downstream build-trigger relationships as an interactive, zoomable DAG. Introduces a new frontend Vite entry, React component with focus-path highlighting and auto-refresh, a backend traversal/DTO package with API endpoints, transient action factories for both Run and Job, and supporting Jelly views for embedded card, sidebar, and full-page contexts.

Changes:

  • New backend buildflow package (action + job action + traversal + DTOs) with build-flow/api endpoint and a transient-action reentrance guard for Run-level registration.
  • New frontend build-flow-view app (DAG layout, formatting utilities, focus path, icons, SCSS) plus shared _card-heading.scss / _card-controls.scss mixins extracted from the Stages graph.
  • Backend (@WithJenkins) and frontend (Vitest) test suites covering traversal, layout, focus paths, SCSS tokens, and status mapping; new i18n keys (buildFlow.*).

Reviewed changes

Copilot reviewed 37 out of 37 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
vite.config.ts Adds build-flow-view Vite entry point
README.md Documents the new Build Flow feature
src/main/resources/.../Messages.properties Adds buildFlow.* i18n keys
src/main/frontend/common/i18n/messages.ts Adds LocalizedMessageKey.buildFlow* and defaults
src/main/frontend/common/styles/_card-heading.scss New shared mixin extracted from Stages card
src/main/frontend/common/styles/_card-controls.scss New shared button/positions mixins
src/main/frontend/pipeline-console-view/.../stages.scss Switches to shared heading mixin
src/main/frontend/pipeline-graph-view/app.scss Switches to shared controls mixin
src/main/frontend/build-flow-view/index.tsx App bootstrap
src/main/frontend/build-flow-view/app.tsx i18n providers and BuildFlow mount
src/main/frontend/build-flow-view/build-flow/main/BuildFlow.tsx Main React component (graph, controls, polling, focus)
src/main/frontend/build-flow-view/build-flow/main/BuildFlow.scss Styles, animations, a11y media queries
src/main/frontend/build-flow-view/build-flow/main/BuildFlowIcons.tsx Inline SVG icons and ToggleButton helper
src/main/frontend/build-flow-view/build-flow/main/BuildFlowLayout.ts Pure DAG/flat layout + formatting
src/main/frontend/build-flow-view/build-flow/main/BuildFlowUtils.ts DOM/dataset helpers, status mapping, computeFullPath
src/main/frontend/build-flow-view/build-flow/main/*.spec.ts Vitest coverage for utils/layout/focus/scss
src/main/frontend/build-flow-view/build-flow/model/BuildFlowModel.ts Frontend DTO types
src/main/java/.../cards/items/BuildFlowRunDetailsItem.java Details-bar item (not wired into aggregator)
src/main/java/.../buildflow/BuildFlowAction.java Run-page Tab with api endpoint
src/main/java/.../buildflow/BuildFlowActionFactory.java Run transient action factory with reentrance guard
src/main/java/.../buildflow/BuildFlowJobAction.java Job-page action with api endpoint
src/main/java/.../buildflow/BuildFlowJobActionFactory.java Job transient action factory
src/main/java/.../buildflow/BuildFlowGraph.java Traversal + DAG assembly + status mapping
src/main/java/.../buildflow/BuildFlowNode.java / BuildFlowEdge.java / BuildFlowResponse.java Backend DTO records and JSON envelope writer
src/main/resources/.../buildflow/BuildFlowAction/*.jelly action, index, summary, widget views
src/main/resources/.../buildflow/BuildFlowJobAction/*.jelly index (full page) and jobMain (embedded card)
src/test/java/.../buildflow/BuildFlowActionTest.java API + action registration tests
src/test/java/.../buildflow/BuildFlowGraphTest.java Traversal/edge-case integration tests

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +10 to +21
public class BuildFlowRunDetailsItem {

public static Optional<RunDetailsItem> get(Run<?, ?> run) {
if (!BuildFlowGraph.hasUpstreamOrDownstream(run)) {
return Optional.empty();
}

RunDetailsItem item = new RunDetailsItem.RunDetail(
new Ionicon("git-network-outline"), ItemContent.of("build-flow", "Build Flow"), "View build chain");
return Optional.of(item);
}
}
Comment on lines +30 to +33
@Override
public String getDisplayName() {
return "Build Flow";
}
</j:when>
<j:otherwise>
<div class="jenkins-!-margin-top-2">
<p>No builds yet.</p>
Comment on lines +466 to +505
<ToggleButton
icon={IconChevronUp}
label=""
active={showUpstream}
onToggle={() => setShowUpstream(!showUpstream)}
tooltip={showUpstream ? "Hide upstream" : "Show upstream"}
/>
<ToggleButton
icon={IconChevronDown}
label=""
active={showDownstream}
onToggle={() => setShowDownstream(!showDownstream)}
tooltip={showDownstream ? "Hide downstream" : "Show downstream"}
/>
<ToggleButton
icon={IconLocate}
label=""
active={focusCurrentFlow}
onToggle={() => setFocusCurrentFlow(!focusCurrentFlow)}
tooltip={
focusCurrentFlow ? "Show full graph" : "Focus current build's flow"
}
/>
<ToggleButton
icon={IconBarChart}
label=""
active={showBuildHistory}
onToggle={() => setShowBuildHistory(!showBuildHistory)}
tooltip={showBuildHistory ? "Hide build history" : "Show build history"}
/>
<ToggleButton
icon={IconRefreshCircle}
label=""
active={autoRefresh}
onToggle={() => setAutoRefresh(!autoRefresh)}
tooltip={autoRefresh ? "Disable auto-refresh" : "Enable auto-refresh"}
/>
</>
);
};
Comment on lines +10 to +22
function computeHighlightedIds(
hoveredNodeId: string | null,
edges: BuildFlowEdgeModel[],
flattenGraph: boolean,
): Set<string> | null {
if (!hoveredNodeId || flattenGraph) return null;
const set = new Set<string>([hoveredNodeId]);
for (const edge of edges) {
if (edge.from === hoveredNodeId) set.add(edge.to);
if (edge.to === hoveredNodeId) set.add(edge.from);
}
return set;
}
Comment on lines +122 to +139
@Test
void recentResults_returnsUpToFiveHistoryItems() throws Exception {
// Create the job once, then run it 3 times
org.jenkinsci.plugins.workflow.job.WorkflowJob job =
TestUtils.createJob(j, "multi-run", "helloWorldScriptedPipeline.jenkinsfile");
j.assertBuildStatus(Result.SUCCESS, job.scheduleBuild2(0));
j.assertBuildStatus(Result.SUCCESS, job.scheduleBuild2(0));
j.assertBuildStatus(Result.SUCCESS, job.scheduleBuild2(0));

WorkflowRun lastRun = job.getLastBuild();

BuildFlowGraph graph = new BuildFlowGraph(lastRun, true, true);
BuildFlowResponse response = graph.build();

BuildFlowNode node = response.nodes().get(0);
assertThat(node.recentResults(), hasSize(3)); // current + 2 previous builds
assertThat(node.recentResults(), everyItem(is("SUCCESS")));
}

@timja timja left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looking really good, I've had a reasonable look over although there's a lot of code.
few comments for improvements

* Registers {@link BuildFlowJobAction} on every {@link Job}.
*/
@Extension
public class BuildFlowJobActionFactory extends TransientActionFactory<Job> {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need this on a job?

Watching it while running it was surprising that it rebuilt the flow for the running build i.e. the last flow disappeared and as new jobs started they appeared in the flow.

as currently built it seems more build specific, you can always turn on the previous build options when viewing it to see how its been running over time.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added this on the job page since that is where a user "lands" first and can easily look through the flow for the latest build, finished or currently running, and browse upstream/downstream without going on the build page (for the latest build at least).

This behavior is the same as how it is in Yet Another Build Visualizer.

From as user perspective, I would like it there.

From the perspective we are discussing it, I suggest we give users a toggle in Global Settings to Show/Hide Build Flow like we have for Stage Names and Duration.

WDYT?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added a toggle in Global Settings which ADMINS can use to enable/disable the Build Flow on Job Page.

For a USER specific toggle, I am thinking where to place it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The USER toggle -

image

Comment thread README.md Outdated

Hidden steps are not displayed by default in the Pipeline Overview, but can be toggled visible using the filter controls.

## Build Flow

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you move this after the screenshots section and include a screenshot of this too

Comment on lines +251 to +270
if (run.isBuilding()) {
return "IN_PROGRESS";
}
Result result = run.getResult();
if (result == null) {
return "IN_PROGRESS";
}
if (result.equals(Result.SUCCESS)) {
return "SUCCESS";
}
if (result.equals(Result.FAILURE)) {
return "FAILURE";
}
if (result.equals(Result.UNSTABLE)) {
return "UNSTABLE";
}
if (result.equals(Result.ABORTED)) {
return "ABORTED";
}
return "NOT_BUILT";

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is simpler, (If we bump Jenkins version we could move to java 21 to simplify further)

Suggested change
if (run.isBuilding()) {
return "IN_PROGRESS";
}
Result result = run.getResult();
if (result == null) {
return "IN_PROGRESS";
}
if (result.equals(Result.SUCCESS)) {
return "SUCCESS";
}
if (result.equals(Result.FAILURE)) {
return "FAILURE";
}
if (result.equals(Result.UNSTABLE)) {
return "UNSTABLE";
}
if (result.equals(Result.ABORTED)) {
return "ABORTED";
}
return "NOT_BUILT";
if (run.isBuilding()) {
return "IN_PROGRESS";
}
Result result = run.getResult();
if (result == null) {
return "IN_PROGRESS";
}
return switch (result.toString()) {
case "SUCCESS", "FAILURE", "UNSTABLE", "ABORTED" -> result.toString();
default -> "NOT_BUILT";
};

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we move to baseline Jenkins 2.555.3 then?

List<String> results = new ArrayList<>(6);
// Include the current build's result as the most recent entry
results.add(mapStatus(run));
Run<?, ?> previous = run.getPreviousBuild();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should avoid loading previous builds into memory if they aren't already there.

This is how JUnit does it:

https://github.com/jenkinsci/junit-plugin/blob/5c8bbfb9798f39a5d31ab95785c1da5e5fcea45e/src/main/java/hudson/tasks/test/AbstractTestResultAction.java#L262-L292


// --- Preferences persistence ---

interface BuildFlowPrefs {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't shorten names, applies to all occurrences:

Suggested change
interface BuildFlowPrefs {
interface BuildFlowPreferences {

@@ -0,0 +1,957 @@
import "./BuildFlow.scss";

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you refactor this file to split some sections of it out logically, e.g. components or grouped functions

its a large file as-is

</svg>
);

export const IconClose = (

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

an example of what should be in a different file, isn't there an existing close icon you can reuse though?

<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core">
<j:if test="${it.shouldDisplayBuildFlow()}">
<div class="jenkins-card"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally this widget would be integrated into the existing stages widget with a button to switch between them.

Maybe an option to enable the second widget but not enabled by default.

Widgets and new tabs

Image

should be added conservatively so that we don't end up with loads of them cluttering the page

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought and propose renaming the Stages widget to Flows, keeping the same icon for a wider coverage of both Stage Flows and Build Flows, WDYT?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have removed the Build Flow Tab and integrated the jelly for it with PipelineConsoleViewAction/widget.jelly.

However, it will render the overview page as follows -
image

To actually move Build Flow below Console, we'd need to either make BuildFlowAction a Tab action again so its widget renders on the Overview without disturbing Stages and Console.

My proposal to rename the Stages Tab as Flows or something else that can be discussed still stands.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my suggestion was to combine them into one widget and allow switching between them.

i.e. Add a build flow button to the stages one

… Flow Integration

- Refactored MainViewVisibility enum to include GRAPH_AND_STAGES, ALL, and BUILD_FLOW_ONLY options.
- Added new styles for Build Flow card in pipeline-console.scss.
- Enhanced user-preference-provider to manage build flow height and collapsed state.
- Improved SplitView component to support collapsible build flow panel.
- Updated PipelineGraphViewConfiguration to include a setting for showing Build Flow on job pages.
- Refactored BuildFlowAction to provide API endpoint without a separate tab.
- Removed obsolete BuildFlowRunDetailsItem class.
- Updated console view actions to integrate Build Flow display logic.
- Added tests to ensure recent results cap is correctly implemented.
@panicking

Copy link
Copy Markdown
Contributor

@adityajalkhare ant plan to continue?

@adityajalkhare

Copy link
Copy Markdown
Contributor Author

@panicking yeah. I'll pick it up after 15th July and see if I can add it to YABV's own repo if it doesn't take a lot of time.

Last I saw it had lot's of upgrade issues open.

If not I'll see if creating a new plugin in itself is a better idea.

But the Build Flow won't be a part of Pipeline Graph View as others suggested above.

@panicking

Copy link
Copy Markdown
Contributor

@panicking yeah. I'll pick it up after 15th July and see if I can add it to YABV's own repo if it doesn't take a lot of time.

Last I saw it had lot's of upgrade issues open.

If not I'll see if creating a new plugin in itself is a better idea.

But the Build Flow won't be a part of Pipeline Graph View as others suggested above.

I think the flow should go here, I don't see any reason why this should not happen. There use case where the jobs are composed by multiple pipeline? Why the flow as a tab is not welcome?

@adityajalkhare

Copy link
Copy Markdown
Contributor Author

@panicking, @janfaracik and @timja have strongly suggested to keep this flow in the OG plugin itself in #1310

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Build Flow view: interactive graph of upstream/downstream build relationships

6 participants